const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
 
function myPromise(fn) {
	this.value = null;
	this.status = PENDING;
	this.fulfilledCallbacks = [];
	this.rejectedCallbacks = [];
 
	function resolve(value) {
		if (this.status === PENDING) {}
	}
 
	function reject(value) {
		if (this.status === PENDING) {}
	}
 
	// 执行回调函数
	try {
		fn(resolve, reject)
	} catch (e) {
		reject(e);
	}
}

function myPromise(fn) {
	this.value = null;
	this.status = PENDING;
	this.fulfilledCallbacks = [];
	this.rejectedCallbacks = [];
 
	function resolve(value) {
		if (this.status === PENDING) {
 
			this.status = FULFILLED;
			this.value = value;
			//执行回调方法
			this.fulfilledCallbacks.forEach(myFn => myFn(this.value))
		}
	}
 
	function reject(value) {
		if (this.status === PENDING) {
			this.status = REJECTED;
			this.value = value;
			//执行回调方法
			this.rejectedCallbacks.forEach(myFn => myFn(this.value))
		}
	}
 
}
// 当状态为FULFILLED(成功)或者reject的时候我们需要把回调的方法放入不同的栈内，可以这样实现
myPromise.prototype.then = function(onFulfilled, onRejected) {
	//等待状态，则添加回调函数到栈中
	if (this.status === PENDING) {
		this.fulfilledCallbacks.push(() => {
			onFulfilled(this.value);
		});
		this.rejectedCallbacks.push(() => {
			onRejected(this.value);
		})
	}
	if (this.status === FULFILLED) {
		onFulfilled(this.value);
	}
 
	if (this.status === REJECTED) {
		onRejected(this.value)
	}
}
 // 完整实现一个promise
 
function myPromise(fn) {
	this.value = null;
	this.status = PENDING; //默认状态
	this.fulfilledCallbacks = [];
	this.rejectedCallbacks = [];
 
	function resolve(value) {
		if (this.status === PENDING) {
			this.status = FULFILLED;
			this.value = value;
			//执行回调方法
			this.fulfilledCallbacks.forEach(myFn => myFn(this.value))
		}
	}
 
	function reject(value) {
		if (this.status === PENDING) {
			this.status = REJECTED;
			this.value = value;
			//执行回调方法
			this.rejectedCallbacks.forEach(myFn => myFn(this.value))
		}
	}
 
	// 执行回调函数
	try {
		fn(resolve, reject)
	} catch (e) {
		reject(e);
	}
}
myPromise.prototype.then = function(onFulfilled, onRejected) {
	let that = this;
	//等待状态，则添加回调函数到栈中
	if (that.status === PENDING) {
		that.fulfilledCallbacks.push(() => {
			onFulfilled(that.value);
		});
		that.rejectedCallbacks.push(() => {
			onRejected(that.value);
		})
	}
	if (that.status === FULFILLED) {
		onFulfilled(that.value);
	}
 
	if (that.status === REJECTED) {
		onRejected(that.value)
	}
}
Promise.prototype.catch =function(undefined, onRejected){
	let that = this;
	//等待状态，则添加回调函数到栈中
	if (that.status === PENDING) {
	
		that.rejectedCallbacks.push(() => {
			onRejected(that.value);
		})
	}
	if (that.status === REJECTED) {
		onRejected(that.value)
	}

}
// 测试一下
let thisreslove = new myPromise((resolve, reject) => {
	// console.log('hello word');
	resolve(5);
});
thisreslove.then((res) => {
	console.log(res);
})
thisreslove.then(() => {
	console.log('成功了');
})
 

// 赵盼补全方法

 /**
        * 静态方法
        * 如果参数是一个promise, 则返回promise本身, 否则返回一个新Promise, 并且直接resolve data数据
        * @param {*} 需要直接resolve的内容
*/
 function resolve(data) {
	if (data instanceof MyPromise) {
		return data;
	} else {
		return new MyPromise(resolve => {
			resolve(data);
		});
	}           
}

function reject(error) {
	return new MyPromise((resolve, reject) => {
		reject(error);
	});
}

function all(proms) {
	return new MyPromise((resolve, reject) => {
		const results = proms.map(p => {
			const obj = {
				result: undefined,
				isResolved: false,
			};
			
			p.then(data => {
				obj.isResolved = true;
				obj.result = data;
				const unResolved = results.find(r => !r.isResolved);
				if (!unResolved) {
					// resolve的内容为所有promise的数据
					resolve(results.map(rst => rst.result));
				}
			}, err => {
				// 如果有任何一个promise reject了, 新promise也reject
				reject(err);
			});
			
			return obj;
		});
	});
}

function race(proms) {
	return new MyPromise((resolve, reject) => {
		proms.forEach(p => {
			p.then(data => {
				resolve(data);
			}, err => {
				reject(err);
			});
		});
	});
}

// 生成器
function* gen(x){
	console.log(55)
	var y = yield x + 2
	console.log(2)
	return y
  }
  
  var g = gen(2)
  g.next() 
// 1
g.next() 
// finally方法
Promise.resolve = function (value){ 
	return new Promise((resolve, reject) => { 
		resolve(value); 
	}); 
}; 
Promise.prototype.finally = function (callback){
	return this.then(data => { 
		 return Promise.resolve(callback()).then(() => data); 
	}, err => {
		 return Promise.resolve(callback()).then(() => {throw err});
	});
};
